/**
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import { computed, defineComponent, ref, SetupContext } from 'vue';
import { NotifyData, NotifyProps, notifyProps } from './notify.props';
import Toast from './components/toast.component';

export default defineComponent({
    name: 'Notify',
    props: notifyProps,
    emits: ['close', 'empty'] as (string[] & ThisType<void>) | undefined,
    setup(props: NotifyProps, context: SetupContext) {
        const notifyClass = computed(() => ({
            'farris-notify': true
        }));

        const defaultNotifyDistance = {
            left: 12,
            right: 12,
            top: 136,
            bottom: 12
        };

        const toasts = ref(props.toasts || []);

        const notifyStyle = computed(() => {
            const styleObject = {
                left: props.position.indexOf('left') > -1 ? `${props.left ? props.left : defaultNotifyDistance.left}px` : '',
                right: props.position.indexOf('right') > -1 ? `${props.right ? props.right : defaultNotifyDistance.right}px` : '',
                top: props.position.indexOf('top') > -1 ? `${props.top ? props.top : defaultNotifyDistance.top}px` : '',
                bottom: props.position.indexOf('bottom') > -1 ? `${props.bottom ? props.bottom : defaultNotifyDistance.bottom}px` : ''
            } as any;
            if (props.position.indexOf('center')) {
                styleObject.left = '50%';
                styleObject.transform = 'translate(-50%, -50%)';
            }
            return styleObject;
        });

        function closeToast(toast: NotifyData) {
            context.emit('close');
        }

        function addToast(toast: NotifyData) {
            if (toasts.value.length >= props.limit) {
                toasts.value.shift();
            }
            toasts.value.push(toast);
            // if (props.timeout) {
            //     this._setTimeout(notify);
            // }
        }

        function invokeToastOnRemoveCallback(toast: NotifyData) {
            if (toast && toast.onRemove) {
                toast.onRemove.call(toast);
            }
        }

        function clear(id: number | string) {
            const targetToastIndex = toasts.value.findIndex((toast: NotifyData) => toast.id === id);
            if (targetToastIndex > -1) {
                const targetToast = toasts.value[targetToastIndex];
                invokeToastOnRemoveCallback(targetToast);
                toasts.value.splice(targetToastIndex, 1);
            }
        }

        function clearAll() {
            toasts.value.forEach((toast: NotifyData) => invokeToastOnRemoveCallback(toast));
            toasts.value.length = 0;
            context.emit('empty');
        }

        context.expose({ addToast, clear, clearAll, closeToast });

        function onClose($event: Event, toast: NotifyData) {
            closeToast(toast);
        }
        function onClick($event: Event) {}

        return () => {
            return (
                <div id={props.id} class={notifyClass.value} style={notifyStyle.value}>
                    {toasts.value.map((toastData: NotifyData) => {
                        return (
                            <Toast
                                options={toastData}
                                animate={props.animate}
                                onClose={($event: any) => onClose($event, toastData)}></Toast>
                        );
                    })}
                </div>
            );
        };
    }
});
